

#import "ServerCommunicationManager.h"

static ServerCommunicationManager* gShareServerCommunicationManager;

#pragma mark -
#pragma mark declear ServerCommunicationManager (private)
@interface ServerCommunicationManager (private)

+ (ServerCommunicationManager*) shareInstance;
@end

#pragma mark -
#pragma mark implement ServerCommunicationManager
@implementation ServerCommunicationManager
@synthesize networkEngine = _networkEngine;
@synthesize sendRequestInfoArray = _sendRequestArray;
@synthesize idGenerator = _idGenerator;
@synthesize urlBook = _urlBook;

+ (id<ServerCommunicationProtocol>) GetServerCommunication
{
    return [ServerCommunicationManager shareInstance];
}

- (id)init
{
    self = [super init];
    if(self)
    {
        _networkEngine = [[NetworkEngine alloc] initWithMaxConcurrent:5 timeoutBySecond:20];
        _sendRequestArray = [[NSMutableArray array] retain];
        _idGenerator = [[RequestIDGenerator alloc] init];
        
        _urlBook = [[RequestUrlBook alloc] initWithConfigFile];
        _protocolList = [[self loadProtocolList] retain];
        _cookieDomain = [NSString stringWithFormat:@"%@",_urlBook.currentHost];
        [_cookieDomain retain];
    }
    return self;
}

-(NSDictionary*)loadProtocolList
{
//    NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile:[IBGUtils findConfigPath:@"ProtocolInfo"]];
//    NSMutableDictionary* tempProtocolDict = [NSMutableDictionary dictionaryWithCapacity:[dict count]];
//    NSEnumerator* keyEnum = [dict keyEnumerator];
//    NSString* key;
//    while(key = [keyEnum nextObject])
//    {
//        NSDictionary* d = [dict objectForKey:key];
//        NSString* v = [d objectForKey:@"response"];
//        [tempProtocolDict setObject:v forKey:key];
//    }
//    return tempProtocolDict;
    return _urlBook.responseDict;
}

- (void)dealloc
{
    ReleaseAndNil(_networkEngine);
    ReleaseAndNil(_sendRequestArray);
    ReleaseAndNil(_idGenerator);
    ReleaseAndNil(_urlBook);
    ReleaseAndNil(_protocolList);
    ReleaseAndNil(_cookieDomain);
    [super dealloc];
}

- (BaseRequest*)findSendRequestInfoById:(NSUInteger)rid
{  
    for(int i=0;i<[_sendRequestArray count];++i)
    {
        BaseRequest* info = (BaseRequest*)[_sendRequestArray objectAtIndex:i];
        if(info.requestId == rid)
            return info;
    }
    return nil;
}


- (BaseRequest*)findSendRequestInfoByRequest:(NetworkRequest*)req
{
    for(int i=0;i<[_sendRequestArray count];++i)
    {
        BaseRequest* info = (BaseRequest*)[_sendRequestArray objectAtIndex:i];
        if(info.request==req)
            return info;
    }
    return nil;
}

- (void)removeSendRequestInfo:(BaseRequest*)info
{
    [_sendRequestArray removeObject:info];
}

//通过requestname查找同名的response
-(BaseResponse*) responseForFuncionName:(NSString*)function
{
//    BaseResponse *response = nil;
//    NSString *responseClassName = [_protocolList objectForKey:function] ;
//    if (responseClassName)
//    {
//        response = [[NSClassFromString(responseClassName) alloc] init];
//    }
//    
//    return [response autorelease];
    BaseResponse *response = nil;
    NSString *responseClassName = [function stringByReplacingOccurrencesOfString:@"Request" withString:@"Response"];
    if (responseClassName)
    {
        response = [[NSClassFromString(responseClassName) alloc] init];
    }
    return [response autorelease];
}

-(BaseResponse*) responseFromRequest:(BaseRequest*)request  ResponseData:(NSData*)responseData
{
    BaseResponse *response = nil;
    NSString *funtionName = request.requestName;
    
    if (funtionName == nil)
    {
        response = [[BaseResponse alloc] init];
        response.ret = RET_DEFAULT_ERROR;
        response.errorType = RESPONSE_TYPE_NOFOUND;
        return [response autorelease];
    }
    else
    {
        if (responseData == nil) {
            response = [[BaseResponse alloc] init];
            response.ret = RET_DEFAULT_ERROR;
            response.errorType = RESPONSE_DATA_NIL;
            response.errorstring = @"返回data为nil";
            response.request = request;
            return [response autorelease];
        }
        else 
        {
            response  = [self responseForFuncionName:funtionName];
            response.data = responseData;
        }
    }
    return response;
}

- (void)setCookie:(NSString*)value forKey:(NSString*)key
{
    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:key forKey:NSHTTPCookieName];
    [cookieProperties setObject:value forKey:NSHTTPCookieValue];
    [cookieProperties setObject:_cookieDomain forKey:NSHTTPCookieDomain];
    [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
    [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
    
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
    /*
     //打印cookie
     NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
     for (NSHTTPCookie *cookie in [cookieJar cookies]) {
     LOGA(@"%@", cookie);
     }
     */
}
- (void)clearCookieForKey:(NSString*)key
{
    NSArray* cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
    for(NSHTTPCookie* cookie in cookies)
    {
        if([[cookie name] compare:key]== NSOrderedSame && [[cookie domain] compare:_cookieDomain]==NSOrderedSame)
        {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
        }
    }
}


#pragma mark implement ServerCommunicationProtocol

- (void)cancelRequest:(RequestID)requestid delegate:(id<ServerCommunicationDelegate>)delegate;
{
    //根据id找 info
    //通知networkengine取消
    //从数组中删除
    BaseRequest* info = [self findSendRequestInfoById:requestid];
    if(info==nil)
        return;
    if(delegate==info.delegate)
    {
        [self removeSendRequestInfo:info];
    }
    
}

- (RequestID)sendRequest:(BaseRequest*)request;
{
    NSString* url = request.url;
    
    if(url==nil)
    {
        NSLog(@"!!!从配置文件获取requestName为:%@的requestUrl获取失败", request.requestName);
        
        BaseResponse* response = [[[BaseResponse alloc] init] autorelease];
        response.request = request;
        response.ret = RET_DEFAULT_ERROR;
        response.errorType = REQUEST_URL_NOFOUND;
        [response parse];
        [request.delegate onRequestFail:response];
        return INVALID_REQUEST_ID;
    }
    NetworkRequest* netrequest = [[[NetworkRequest alloc] initWithUrl:url method:request.method data:request.dataDict delegate:self version:request.version] autorelease];
    if(request.binaryDataArray!=nil && [request.binaryDataArray count]>0)
    {
        for(int i=0;i<[request.binaryDataArray count];++i)
        {
            NSDictionary* dict = [request.binaryDataArray objectAtIndex:i];
            if([dict isKindOfClass:[NSDictionary class]])
            {
                NSString* key = [dict objectForKey:DATA_KEY];
                NSString* filename = [dict objectForKey:FILENAME_KEY];
                NSString* mimetype = [dict objectForKey:MIME_KEY];
                NSData* data = [dict objectForKey:BIANRY_DATA_KEY];
                [netrequest setBinaryData:data withFilename:filename withContentType:mimetype withKey:key];
                //- (void)setBinaryData:(NSData*)data withFilename:(NSString*)filename withContentType:(NSString*)contentType withKey:(NSString*)key;
            }
        }
    }
    if(request.fileDataArray!=nil && [request.fileDataArray count]>0)
    {
        for(int i=0;i<[request.binaryDataArray count];++i)
        {
            NSDictionary* dict = [request.binaryDataArray objectAtIndex:i];
            if([dict isKindOfClass:[NSDictionary class]])
            {
                NSString* key = [dict objectForKey:DATA_KEY];
                NSString* filename = [dict objectForKey:FILENAME_KEY];
                NSString* mimetype = [dict objectForKey:MIME_KEY];
                NSString* filepath = [dict objectForKey:FILE_PATH_KEY];
                [netrequest setFileData:filepath withFilename:filename withContentType:mimetype withKey:key];
                //- (void)setFileData:(NSString*)filepath withFilename:(NSString*)filename withContentType:(NSString*)contentType withKey:(NSString*)key;
            }
        }
    }
    
    /*
    if(_cookieDictionary!=nil)
    {
        NSEnumerator* keyEnumerator = [_cookieDictionary keyEnumerator];
        NSString* key;        
        while ((key = [keyEnumerator nextObject])) {
            [netrequest setCookie:[_cookieDictionary objectForKey:key] key:key]; 
        }
    }
     */
    
    NSInteger rid = [self.idGenerator generateReqestID];
    if([self findSendRequestInfoById:rid]!=nil)
    {
        return INVALID_REQUEST_ID;
    }

    request.requestId = rid;
    request.request = netrequest;
    [self.sendRequestInfoArray addObject:request];
    
    [self.networkEngine addNetworkRequest:netrequest];
    return rid;
}


#pragma mark implement NetworkEngineDelegate
- (void)onRequestFinish:(NetworkRequest*)request data:(NSData*)data
{
    BaseRequest* info = [self findSendRequestInfoByRequest:request];
    
    //gbk编码
    NSStringEncoding gbkEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);

    NSString *resultString = [[NSString alloc] initWithData:data encoding:gbkEncoding];
    
    NSLog(@"============= result ==============:%@", resultString);
    if(info==nil)
    {
        return;
    }
    BaseResponse* response = [self responseFromRequest:info ResponseData:data];
    response.request = info;
    [response parse];
    if(response.ret==RET_SUCCESS)
    {
        response.errorType = NO_ERROR;
        [info.delegate onRequestSuccess:response];
    }else {
        response.errorType = RESPONSE_PARSE_RET_ERROR;
        [info.delegate onRequestFail:response];    
    }
    
    [self removeSendRequestInfo:info];
    //从数组中删除
    
}
- (void)onRequestFail:(NetworkRequest*)request responseStatusCode:(int)statuscode
{
    //返回错误
    BaseRequest* info = [self findSendRequestInfoByRequest:request];
    if(info==nil)
    {
        return;
    }
    BaseResponse* response = [[[BaseResponse alloc]init] autorelease];
    response.request = info;
    response.ret = RET_DEFAULT_ERROR;
    response.errorType = NETWORK_ERROR;
    response.errorstring = @"网络错误，请重试";
    response.msg = @"网络错误，请重试";
    if(info.delegate)
    {
        [info.delegate onRequestFail:response];
    }
    //从数组中删除
    [self removeSendRequestInfo:info];
}

#pragma mark -
#pragma mark 动态切环境时，需要重置数据
- (void)resetUrlBookAndCookieDomain
{
    ReleaseAndNil(_urlBook);
    ReleaseAndNil(_protocolList);
    ReleaseAndNil(_cookieDomain);
}

- (void)setUrlBookAndCookieDomain
{
    _urlBook = [[RequestUrlBook alloc] initWithConfigFile];
    _protocolList = [[self loadProtocolList] retain];
    _cookieDomain = [NSString stringWithFormat:@"%@",_urlBook.currentHost];
    [_cookieDomain retain];
}

@end

#pragma mark -
#pragma mark implement ServerCommunicationManager (private)
@implementation ServerCommunicationManager (private)
+ (ServerCommunicationManager*) shareInstance
{
    if(gShareServerCommunicationManager==nil)
    {
        gShareServerCommunicationManager = [[ServerCommunicationManager alloc] init];
    }
    return gShareServerCommunicationManager;
}




@end